<template>
  <div class="image-upload">
    <el-upload
      class="upload-demo"
      :action="action"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
      :before-upload="beforeUpload"
      :accept="accept"
      :limit="limit"
      :list-type="listType"
      :disabled="disabled"
      :multiple="multiple"
      :show-file-list="showFileList"
      :http-request="customUpload"
    >
      <el-button type="primary" :disabled="disabled">{{ buttonText }}</el-button>
      <template #tip>
        <div class="el-upload__tip" v-if="showTip">
          {{ tipText }}
        </div>
      </template>
    </el-upload>
    
    <!-- 显示已上传的图片 -->
    <div class="image-preview" v-if="localImageUrl">
      <img :src="localImageUrl" class="preview-image" @click="showImageDialog = true" />
      <div class="image-click-tip">点击查看大图</div>
      <div class="image-delete-btn" @click.stop="handleDeleteImage">
        <el-icon><Delete /></el-icon>
      </div>
    </div>
    
    <!-- 图片放大查看对话框 -->
    <el-dialog v-model="showImageDialog" width="800px" title="图片查看" :append-to-body="true" center>
      <div class="image-dialog-content">
        <img :src="localImageUrl" class="large-preview-image" />
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'

const props = defineProps({
  // 上传地址
  action: {
    type: String,
    required: true
  },
  // 文件类型限制
  accept: {
    type: String,
    default: '.jpg,.jpeg,.png'
  },
  // 上传数量限制
  limit: {
    type: Number,
    default: 1
  },
  // 列表类型
  listType: {
    type: String,
    default: 'picture'
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否显示文件列表
  showFileList: {
    type: Boolean,
    default: true
  },
  // 按钮文字
  buttonText: {
    type: String,
    default: '点击上传'
  },
  // 是否显示提示
  showTip: {
    type: Boolean,
    default: true
  },
  // 提示文字
  tipText: {
    type: String,
    default: '只能上传jpg/png文件，且不超过5MB'
  },
  // 文件大小限制（MB）
  fileSize: {
    type: Number,
    default: 5
  },
  // 已上传的图片URL
  imageUrl: {
    type: String,
    default: ''
  },
  // 上传系统渠道
  sysUploadType: {
    type: String,
    default: 'system'
  }
})

const emit = defineEmits(['update:modelValue', 'success', 'error'])

// 本地图片URL
const localImageUrl = ref('')

// 显示大图对话框
const showImageDialog = ref(false)

// 监听imageUrl变化
watch(() => props.imageUrl, (newVal) => {
  if (newVal) {
    // 检查是否已经包含http，如果不包含则添加action作为基础URL
    if (newVal.url.startsWith('http')) {
      localImageUrl.value = newVal.url
    } else {
      // 根据需要调整URL
      localImageUrl.value = import.meta.env.VITE_API_URL + newVal.url
    }
  } else {
    localImageUrl.value = ''
  }
})

// 初始化时设置图片URL
if (props.imageUrl) {
  // 检查是否已经包含http，如果不包含则添加action作为基础URL
  if (props.imageUrl.startsWith('http')) {
    localImageUrl.value = props.imageUrl
  } else {
    // 根据需要调整URL
    localImageUrl.value = import.meta.env.VITE_API_URL + props.imageUrl
  }
}

// 处理删除图片
const handleDeleteImage = (event) => {
  // 阻止事件冒泡，防止触发图片点击事件
  event?.stopPropagation()
  
  // 清空本地图片URL
  localImageUrl.value = ''
  
  // 触发错误事件，通知父组件图片已删除
  emit('error')
  
  // 关闭大图对话框（如果正在显示）
  showImageDialog.value = false
  
  ElMessage.success('图片已删除')
}

// 自定义上传方法
const customUpload = (options) => {
  if (options.file) {
    // 创建表单数据
    const formData = new FormData()
    // 添加文件到FormData
    formData.append('files', options.file)
    // // 添加上传类型到FormData
    // if (props.sysUploadType && props.sysUploadType.trim() !== '') {
    //   formData.append('sysUploadType', props.sysUploadType)
    // }
    
    // 使用原生XHR但不使用upload事件监听器
    const xhr = new XMLHttpRequest()
    // 打开连接
    xhr.open('POST', options.action, true)
    
    // 获取token并设置Authorization header
    const token = localStorage.getItem('token')
    if (token) {
      xhr.setRequestHeader('Authorization', `Bearer ${token}`)
    }
    
    // 设置headers - 不设置Content-Type，让浏览器自动设置multipart/form-data的boundary
    if (options.headers) {
      Object.keys(options.headers).forEach(key => {
        xhr.setRequestHeader(key, options.headers[key])
      })
    }
    
    // 只监听readyState变化来处理上传完成和错误
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          const response = JSON.parse(xhr.responseText)
          if (options.onSuccess) {
            options.onSuccess(response)
          }
        } else {
          const error = new Error(`Upload failed with status ${xhr.status}`)
          console.log(error)
          if (options.onError) {
            options.onError(error)
          }
        }
      }
    }
    
    // 直接发送请求，不使用upload事件
    xhr.send(formData)
  }
}

// 上传成功
const handleUploadSuccess = (response, uploadFile) => {
  const imageUrl = response.data
  localImageUrl.value = imageUrl
  emit('success', imageUrl)
  ElMessage.success('上传成功')
}

// 上传失败
const handleUploadError = (error) => {
  localImageUrl.value = ''
  emit('error', error)
  ElMessage.error('上传失败，请重试')
}

// 上传前校验
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < props.fileSize

  if (!isImage) {
    ElMessage.error('上传文件只能是图片格式!')
    return false
  }
  if (!isLt5M) {
    ElMessage.error(`上传图片大小不能超过 ${props.fileSize}MB!`)
    return false
  }
  return true
}
</script>

<style scoped>
.image-upload {
  display: inline-block;
}

.image-preview {
  margin-top: 10px;
  position: relative;
  display: inline-block;
}

.preview-image {
  width: 100px;
  height: 100px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 5px;
  cursor: pointer;
  transition: all 0.3s;
}

.preview-image:hover {
  opacity: 0.8;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.image-click-tip {
  font-size: 12px;
  color: #909399;
  text-align: center;
  margin-top: 5px;
}

.image-dialog-content {
  display: flex;
  justify-content: center;
  align-items: center;
}

.large-preview-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.image-delete-btn {
  position: absolute;
  top: -8px;
  right: -8px;
  background-color: #f56c6c;
  color: white;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  font-size: 12px;
  z-index: 1;
  opacity: 0.8;
  transition: all 0.3s;
}

.image-delete-btn:hover {
  opacity: 1;
  transform: scale(1.1);
}
</style>
